﻿namespace MicroCloud.Systems
{
    /// <summary>
    /// 字典数据存储接口
    /// </summary>
    public interface IKeyValueStore
    {
        #region 属性
        /// <summary>
        /// 获取 字典数据查询数据集
        /// </summary>
        IQueryable<KeyValue> KeyValues { get; }

        #endregion

        #region KeyValue
        /// <summary>
        /// 获取指定键名的数据项，先从缓存中获取，如果不存在，再从数据库查找并缓存
        /// </summary>
        /// <param name="key">键名</param>
        /// <returns>数据项</returns>
        IKeyValue GetByKey(string key);

        /// <summary>
        /// 获取指定根节点的数据项，如输入“System.User.”，则查找所有键以此开头的项
        /// </summary>
        /// <param name="rootKey">根键路径</param>
        /// <returns>多个数据项</returns>
        IKeyValue[] GetByRootKey(string rootKey);

        /// <summary>
        /// 检查字典数据是否存在
        /// </summary>
        /// <param name="predicate">检查谓语表达式</param>
        /// <param name="id">字典数据编号</param>
        /// <returns>字典数据是否存在</returns>
        Task<bool> CheckExists(Expression<Func<KeyValue, bool>> predicate, long id = default);

        /// <summary>
        /// 添加或更新字典数据
        /// </summary>
        /// <param name="key">数据键名</param>
        /// <param name="value">数据值</param>
        /// <param name="display">显示名称</param>
        /// <param name="remark">备注</param>
        /// <param name="isLocked">是否锁定</param>
        /// <returns>业务操作结果</returns>
        Task<OperationResult> CreateOrUpdate(string key, object value, string display = "", string remark = "", bool isLocked = false);

        /// <summary>
        /// 添加或更新字典数据
        /// </summary>
        /// <param name="dtos">字典数据DTO</param>
        /// <returns>业务操作结果</returns>
        Task<OperationResult> CreateOrUpdate(params IKeyValue[] dtos);

        /// <summary>
        /// 删除字典数据
        /// </summary>
        /// <param name="ids">字典数据编号</param>
        /// <returns>业务操作结果</returns>
        Task<OperationResult> Delete(params long[] ids);

        /// <summary>
        /// 删除以根键路径为起始的所有字典项，如输入“System.User.”，所有键以此开头的项都会被删除
        /// </summary>
        /// <param name="rootKey">根键路径</param>
        /// <returns>业务操作结果</returns>
        Task<OperationResult> DeleteByRootKey(string rootKey);

        #endregion

        #region ISetting
        /// <summary>
        /// 获取或创建设置信息
        /// </summary>
        /// <typeparam name="TSetting">设置类型</typeparam>
        /// <returns>设置实例，数据库中不存在相应节点时返回默认值</returns>
        TSetting GetSetting<TSetting>() where TSetting : ISetting, new();

        /// <summary>
        /// 保存设置信息
        /// </summary>
        /// <param name="setting">设置信息</param>
        Task<OperationResult> SaveSetting(ISetting setting);

        #endregion
    }
}